package cn.jiedanba.itext5.gm.sign.test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.bouncycastle.jcajce.provider.digest.SM3;
import org.ofdrw.gm.ses.v4.SESeal;
import org.ofdrw.sign.signContainer.SESV4Container;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.security.TSAClient;

import cn.jiedanba.itext5.BCProvider;
import cn.jiedanba.itext5.gm.sign.ITextGM;
import cn.jiedanba.itext5.gm.sign.timestamp.GMTSAClient;
import cn.jiedanba.itext5.gm.sign.timestamp.GMTimeStampHook;
import cn.jiedanba.itext5.gm.sign.vo.GetPdfHash;
import cn.jiedanba.itext5.gm.sign.vo.GetPdfHashParamVo;
import cn.jiedanba.itext5.util.PkiUtil;

/**
 * 国密 pdf签名测试
 * 
 * @author dell
 *
 */
public class SignPdf extends BCProvider {

	private static String cert = "MIIC7jCCApSgAwIBAgIKEzcVzWqfaSVCWDAKBggqgRzPVQGDdTBoMQswCQYDVQQGEwJDTjE2MDQGA1UECgwtRGlnaXRhbCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgQ2VudGVyIENvLiwgTHRkMSEwHwYDVQQDDBhHbG9iYWwgSWRlbnRpdHkgQ0EgLSBTTTIwHhcNMjIwODA1MDMzOTUxWhcNMjQwODA0MDMzOTUxWjCBozELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCeW5v+S4nOecgTESMBAGA1UEBwwJ5rex5Zyz5biCMScwJQYDVQQKDB7mt7HlnLPmtYvor5Xnp5HmioDmnInpmZDlhazlj7gxGjAYBgNVBAsMETkxNDQwMzIwNzI4NTg2NDZUMScwJQYDVQQDDB7mt7HlnLPmtYvor5Xnp5HmioDmnInpmZDlhazlj7gwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAR8vc0gHV7R+n4vWksUk7HLqT/qZcZXR48EIgpB0RktvBOUpJX/MwZYNc3YWDi0KJmqg68aJSEJQNG9XF3I1okmo4HpMIHmMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFNRR+dORN3q7vyMsWhValmZbLYk0MB0GA1UdDgQWBBTXFhs+z387v0faSqjOQLdsBFINojASBggrBgEEAQlwAwQGFgRUZXN0MCwGA1UdJQEB/wQiMCAGCisGAQQBgjcKAwwGCCsGAQUFBwMEBggrBgEFBQcDAjBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vY3JsLmppZWRhbmJhLmNuL2NybC9HbG9iYWxJZGVudGl0eUNBLVNNMi5jcmwwCgYIKoEcz1UBg3UDSAAwRQIhAJFfPgPlWTG9N+88ge9SI53wTz5atDjJ7OJ2g2C4xKe4AiAewqjzhv7SPKl3ucqDwka/0ylIxW8I08rXvYf4sE4q5Q==";
	private static String privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg5PcUVT35q5vpffnZ7aUR8/7GQS2O5KbvRZl568OeoQ6gCgYIKoEcz1UBgi2hRANCAAR8vc0gHV7R+n4vWksUk7HLqT/qZcZXR48EIgpB0RktvBOUpJX/MwZYNc3YWDi0KJmqg68aJSEJQNG9XF3I1okm";

	public static void sign() throws IOException, GeneralSecurityException, DocumentException {
		GetPdfHashParamVo paramVo = new GetPdfHashParamVo();
		Path pdf = Paths.get("src/main/resources", "test.pdf");
		paramVo.setPdf(Files.readAllBytes(pdf));
		paramVo.setPageNo(1);
		paramVo.setLlx(240);
		paramVo.setLly(290);
		paramVo.setUrx(paramVo.getLlx() + 120);
		paramVo.setUry(paramVo.getLly() + 120);
		Path seal = Paths.get("src/main/resources", "深圳测试科技有限公司.seal");
		paramVo.setSeal(SESeal.getInstance(Files.readAllBytes(seal)));
		paramVo.setLocation("深圳");
		paramVo.setReason("国密电子签章测试");

		// 创建签名域，获取pdf文件摘要
		GetPdfHash getPdfHash = ITextGM.getPdfHash(paramVo);

		TSAClient tsaClient = new GMTSAClient(new URL("https://gateway.ca.jiedanba.cn/tsa/sign?type=SM2"), null, null,
				new SM3.Digest());

		PrivateKey prvKey = PkiUtil.getPrivateKey(Base64.decodeBase64(privateKey));

		X509Certificate signCert = PkiUtil.readX509Certificate(Base64.decodeBase64(cert));

		// 签署摘要，以下为模拟外部签名测试，电子签章请使用符合国家规范具有国家型号证书的设备进行
		SESV4Container signature = new SESV4Container(prvKey, paramVo.getSeal(), signCert);
		GMTimeStampHook timeStampHook = new GMTimeStampHook(tsaClient);
		signature.setTimeStampHook(timeStampHook);
		byte[] p7 = signature.sign(getPdfHash.getDigesHash(), "Signature.xml");
		// 签署pdf
		byte[] signSuccess = ITextGM.signDeferred(getPdfHash.getEmptySignaturePdf(), p7, getPdfHash.getFieldName());

		FileUtils.writeByteArrayToFile(new File("src/main/resources/sign.pdf"), signSuccess);
	}

	public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException {
		sign();
	}
}
